/**
  ******************************************************************************
  * File Name          : mbtcptsk.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "mbtcp.h"
#include "modbus.h"
#include <string.h>

TaskHandle_t xModbusTCP_Thd = NULL;
StaticTask_t xModbusTCP_Tcb;
StackType_t  xModbusTCP_Stk[MODBUSTCP_STACK_SIZE];

Ethernet_SendQueStru mbtcp_txbuf = {
  .sn = ETH_SOCK_NUM_MBTCP,
  .type = 1,
  .dest_ip = {192,168,6,43},
  .dest_port = 33778,
  .len = 23,
  .buf = "make test socket in 1\r\n",
};

static Ethernet_FeedbackDataStru mbtcp_rxbuf;

static volatile uint8_t tcp_connected = 0;

static void tcp_client_connection_keeps(void)
{
  uint8_t sr;
  static TickType_t xLastWakeTime = 0;

  if(((xTaskGetTickCount() - xLastWakeTime) >= 1000) || (tcp_connected == 0))
  {
    xLastWakeTime = xTaskGetTickCount();

    sr = ethif_get_socket_sr(ETH_SOCK_NUM_MBTCP);
    switch(sr)
    {
      case SOCK_UDP:
      case SOCK_IPRAW:
      case SOCK_MACRAW:
      case SOCK_CLOSE_WAIT:
        tcp_connected = 0;
        ethif_close(ETH_SOCK_NUM_MBTCP); 

      case SOCK_CLOSED:
        tcp_connected = 0;
        ethif_socket(ETH_SOCK_NUM_MBTCP, Sn_MR_TCP, ETH_SOCK_LCPORT_MBTCP, 0);

      case SOCK_INIT:
        tcp_connected = 0;
        ethif_listen(ETH_SOCK_NUM_MBTCP);
        break;

      case SOCK_LISTEN:
        tcp_connected = 0;
        break;

      case SOCK_SYNRECV:
        tcp_connected = 0;
        break;

      case SOCK_ESTABLISHED:
        tcp_connected = 1;
        break;

      default:
        break;
    }
  }
}

static void feedback_process(TickType_t blocktime)
{
  uint16_t i;
  Ethernet_FeedbackCtrlStru ctrl;
  QueueSetMemberHandle_t activated_qhd;
  
  activated_qhd = xQueueSelectFromSet(mbtcp_ethfb_qshd, blocktime);
  if(activated_qhd == mbtcp_ethfb_qhd[CQUE])         /* 中断消息 */
  {
    if(xQueueReceive(activated_qhd, &ctrl, 0) !=NULL)
    {
      switch(ctrl.type)
      {
        case ETH_FB_CONNECTED:
          tcp_connected = 1;
          break;

        case ETH_FB_DISCONNECTED:
          tcp_connected = 0;
          break;

        case ETH_FB_TIMEOUT:
          tcp_connected = 0;
          break;

        default:
          break;
      }
    }
  }
  else if(activated_qhd == mbtcp_ethfb_qhd[DQUE])    /* 数据消息接收 */
  {
    if(xQueueReceive(activated_qhd, &mbtcp_rxbuf, 0) !=NULL)
    {
      printf("mbtcp rcv len:%d\r\nmbtcp rcv data:",mbtcp_rxbuf.len);
      for(i=0; i<mbtcp_rxbuf.len; i++)
      {
        printf("%02X ",mbtcp_rxbuf.buf[i]);
      }
      printf("\r\n");

      mbtcp_txbuf.len = 0;
      if(modbus_tcp_process(mbtcp_rxbuf.buf, mbtcp_rxbuf.len, mbtcp_txbuf.buf, &mbtcp_txbuf.len) == 0)
      {
        if(mbtcp_txbuf.len != 0){
          ethif_tosend(&mbtcp_txbuf);
        }
      }
    }
  }
}

void vModbusTCP_Task(void * pvParameters)
{
  modbus_init();
  
  while(1)
  {
    tcp_client_connection_keeps();

    feedback_process(1000);
  }
}
